<template>
  <div class="city-picker">
    <div class="col province">
      <div class="title">省份</div>
      <div class="select-box">
        <el-checkbox
          class="all-check"
          :indeterminate="getProvinceInd()"
          v-model="provinceInfo.checkAll"
          @change="onChangeProvinceAll"
        >
          全选
        </el-checkbox>
        <div
          :class="{ touched: index == provinceInfo.touchedId || item.checked }"
          class="select"
          v-for="(item, index) of province"
          :key="index"
        >
          <!-- 省单选 -->
          <el-checkbox
            :indeterminate="getSingleInd(item, index, 'city')"
            v-model="item.checked"
            @change="onChangeProvince($event, index)"
          ></el-checkbox>
          <p @click="onChoose('province', index)">
            {{ item.name }} <i class="el-icon-arrow-right"></i>
          </p>
        </div>
      </div>
    </div>
    <div class="col city" v-if="Object.values(this.cities).length">
      <div class="title">城市</div>
      <div class="select-box">
        <el-checkbox
          class="all-check"
          :indeterminate="getCityInd()"
          v-model="cityInfo.checkAll"
          @change="onChangeCityAll"
        >
          全选
        </el-checkbox>
        <div
          class="select"
          :class="{ touched: index == cityInfo.touchedId || item.checked }"
          v-for="(item, index) of cities"
          :key="index"
        >
          <!-- 市单选 -->
          <el-checkbox
            :indeterminate="getSingleInd(item, index, 'dis')"
            v-model="item.checked"
            @change="onChangeCity($event, index)"
          ></el-checkbox>
          <p @click="onChoose('city', index)">
            {{ item.name }}
            <i v-show="hasNext" class="el-icon-arrow-right"></i>
          </p>
        </div>
      </div>
    </div>
    <div class="col distingct" v-if="Object.values(this.distingct).length">
      <div class="title">区</div>
      <div class="select-box">
        <el-checkbox
          class="all-check"
          :indeterminate="getDisInd()"
          v-model="distingctInfo.checkAll"
          @change="onChangeDisAll"
        >
          全选
        </el-checkbox>
        <div
          class="select"
          :class="{ touched: index == distingctInfo.touchedId || item.checked }"
          v-for="(item, index) of distingct"
          :key="index"
        >
          <el-checkbox v-model="item.checked"></el-checkbox>
          <p @click="onChoose('distingct', index)">{{ item.name }}</p>
        </div>
      </div>
    </div>
    <div class="col select-list">
      <div class="title">
        <span>已选：{{ selectList.length }}</span>
        <span class="clear" @click="clear">清空</span>
      </div>
    </div>
    <span @click="getData">dd</span>
  </div>
</template>
<script>
import { citiesMap } from "../assets/data/cityies";
export default {
  data() {
    return {
      citiesMap,
      province: [],
      cities: [],
      distingct: [],
      pCode: 0,
      hasNext: false,
      provinceInfo: {
        checkAll: false,
        indeterminate: false,
        touchedId: "",
      },
      cityInfo: {
        checkAll: false,
        indeterminate: false,
        touchedId: "",
      },
      distingctInfo: {
        checkAll: false,
        indeterminate: false,
        touchedId: "",
      },
      selectList: [],
      municipalityCity: ["110000", "120000", "310000", "500000"],
    };
  },
  watch: {
    province: {
      handler(val) {
      },
      deep: true,
    },
  },
  methods: {
    getData(){
      console.log(this.citiesMap)
    },
    // 初始化数据
    transData() {
      for (let i in this.citiesMap) {
        let c = this.citiesMap[i];
        for (let k in c) {
          let name = c[k];
          if (typeof name != "string") return;
          let pcodes = i.length ? i.split(",") :[]

          c[k] = {
            name: name,
            checked: false,
            code: k,
            pCode: pcodes.length?pcodes[pcodes.length-1] : "",
          };
        }
      }
    },
    getCheckStatus(origin) {
      let list = [];
      for (let i in origin) {
        list.push(origin[i].checked);
      }
      let hasCheck = list.some((it) => it);
      let allCheck = list.every((it) => it);
      let noCheck = list.every((it) => !it);
      list = null;
      return {
        hasCheck,
        allCheck,
        noCheck,
      };
    },
    getSingleInd(item, index) {
      // 判断下一级数据是否全部选中
      for(let i in this.citiesMap){
        // 市级
        let codeList = i.split(',')
        if(codeList[codeList.length-1] == index){
          // 下一级
          const nextLevelMap = this.citiesMap[i]
          let checkList = []
          for(let j in nextLevelMap){
            checkList.push(nextLevelMap[j].checked)
          }
          const allCheck = checkList.every(Boolean)
          const noCheck = checkList.every(it=>!it)
          const hasCheck = checkList.some(it=>it)
          // 
          if(allCheck){
            item.checked = true
            item.partCheck = false
            return false
          }
          if(noCheck){
            item.checked = false
            item.partCheck = false
            return false
          }
          if(hasCheck){
            // 存在部分选择
            item.partCheck = true
            item.checked = false
            return true
          }
        }
      }
    },

    // 判断省下市/区是否全选
    getSingleProvinceInd(item, index, type = "city") {},
    // 判断province是否全选
    getProvinceInd() {
      return this.getComputedInd("province");
    },
    getCityInd() {
      return this.getComputedInd("city");
    },
    getDisInd() {
      return this.getComputedInd("dis");
    },
    // 计算部分选择状态
    getComputedInd(type) {
      const { data, info } = this.getDataMap(type);
      const { hasCheck, allCheck, noCheck } = this.getCheckStatus(data);
      if (allCheck) {
        info.checkAll = true;
        return false;
      }
      if (noCheck) {
        info.checkAll = false;
        return false;
      }
      if (hasCheck) return true;
    },
    onSingleCheckChange(val,code,type){
      this.onChoose(type=="province"?'province':'city', code);
      let data = type=="province" ? this.cities : this.distingct
      console.log(data)
      if (val) {
          for (let i in data) {
            console.log('-----',data[i])
            data[i].checked = true;
          }
      } else {
          for (let i in data) {
            data[i].checked = false;
          }
      }
      this.$forceUpdate()
    },
    // 单选省
    onChangeProvince(val, code) {
      this.onSingleCheckChange(val,code,'province')
    },
    // 单选市
    onChangeCity(val,code){
      this.onSingleCheckChange(val,code,'city')
    },
    // 全选省
    onChangeProvinceAll() {
      this.onChangeAll("province");
    },
    // 全选市
    onChangeCityAll() {
      this.onChangeAll("city");
    },
    // 全选区
    onChangeDisAll() {
      this.onChangeAll("dis");
    },
    onChangeAll(type) {
      const { data, info } = this.getDataMap(type);
      const { hasCheck, allCheck, noCheck } = this.getCheckStatus(data);
      console.log(hasCheck,allCheck,noCheck,info)
      if (allCheck) {
        for (let i in data) {
          data[i].checked = false;
        }
        info.checkAll = false;
        return;
      }
      if (hasCheck || noCheck) {
        for (let i in data) {
          data[i].checked = true;
        }
        info.checkAll = true;
        return;
      }
    },
    getDataMap(type) {
      const map = {
        province: {
          data: this.province,
          info: this.provinceInfo,
        },
        city: {
          data: this.cities,
          info: this.cityInfo,
        },
        dis: {
          data: this.distingct,
          info: this.distingctInfo,
        },
      };
      let data = map[type].data;
      let info = map[type].info;
      return {
        data,
        info,
      };
    },
    onChoose(type, code) {
      let cityCode = `0,${code}`;
      const isMunicipalityCity = this.municipalityCity.includes(code);
      if (type == "province") {
        // 直辖市，直接展示区
        // if (isMunicipalityCity) {
        //   this.hasNext = false;
        //   cityCode = cityCode = `0,${code},${Number(code) + 100}`;
        // } else {
        //   this.hasNext = true;
        // }
        this.cities = this.citiesMap[cityCode];
        this.pCode = code;
        this.distingct = {};
        this.provinceInfo.touchedId = code;
      }
      if (type == "city") {
        // if (this.municipalityCity.includes(this.pCode)) {
        //   return (this.distingct = {});
        // }
        let distingctCode = `0,${this.pCode},${code}`;
        this.distingct = this.citiesMap[distingctCode];
        this.cityInfo.touchedId = code;
      }
      if (type == "distingct") {
        this.distingctInfo.touchedId = code;
      }
    },
    clear() {},
  },
  mounted() {
    this.transData();
    this.province = this.citiesMap[0];
  },
};
</script>
<style scoped>
.city-picker {
  display: flex;
  margin: 30px;
}
.city-picker .col {
  flex: 1;
  border: 1px solid #ccc;
  min-width: 200px;
}

.city-picker .col:nth-child(2),
.city-picker .col:nth-child(3) {
  border-left: 0;
}
.city-picker .col.select-list {
  margin-left: 20px;
  border-left: 1px solid #ccc;
}
.city-picker .col.select-list .title {
  display: flex;
  justify-content: space-between;
}
.city-picker .col.select-list .title .clear {
  color: #197afb;
  cursor: pointer;
}
.city-picker .title {
  background: #fafbff;
  padding: 10px;
  font-size: 14px;
  border-bottom: 1px solid #ccc;
}
.city-picker .select-box {
  height: 350px;
  overflow: auto;
  min-width: 200px;
  flex: 1;
}
.city-picker .select-box .all-check {
  padding: 10px 0 0 10px;
}
.city-picker .select-box .select {
  color: #656366;
  font-size: 14px;
  margin: 5px 0;
  display: flex;
  align-items: center;
  padding: 5px 10px;
}
.city-picker .select-box .select.touched {
  color: #409eff;
}
.city-picker .select-box .select:hover {
  background: #f5f7fa;
}
.city-picker .select-box .select p {
  flex: 1;
  display: flex;
  justify-content: space-between;
  margin: 0;
  padding: 0;
  padding-left: 8px;
  cursor: pointer;
}
.city-picker
  .select-box
  .select
  p:ac
  .city-picker
  .select-box
  .select
  .check-icon {
  width: 20px;
  height: 20px;
}

.city-picker .select-box::-webkit-scrollbar {
  width: 10px;
  height: 1px;
}
.city-picker .select-box::-webkit-scrollbar-thumb {
  border-radius: 10px;
  height: 20px;
  background: #dddee2;
}
.city-picker .select-box::-webkit-scrollbar-track {
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.05);
}
</style>
